package com.wps.wdztv6.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wps.wdztv6.common.R;
import com.wps.wdztv6.config.WdztAppInfoConfig;
import com.wps.wdztv6.entity.ThirdFile;
import com.wps.wdztv6.mapper.FileMapper;
import com.wps.wdztv6.service.FileService;
import com.wps.wdztv6.utils.DateUtil;
import com.wps.wdztv6.utils.WPS4Util;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.util.List;

@Service
@Log4j2
public class FileServiceImpl implements FileService {
    @Autowired
    private FileMapper fileMapper;

    @Autowired
    ResourceLoader resourceLoader;

    @Value("${upload.file.savepath}")
    private String savePath;

    @Value("${myserver.api}")
    private String downloadUrl;

    @Override
    public R<ThirdFile> getFileByFileVersionId(String fileId) {
        ThirdFile file = fileMapper.selectById(fileId);
        if (file == null) {
            return R.failed("文件不存在:" + fileId);
        }
        return R.success("文件查询成功", file);
    }

    @Override
    public R<ThirdFile> getLatestFileByFileId(String fileId) {
        LambdaQueryWrapper<ThirdFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdFile::getGroupFileId, fileId);
        queryWrapper.orderByDesc(ThirdFile::getVersion);
        queryWrapper.last("limit 1");
        ThirdFile file = fileMapper.selectOne(queryWrapper);
        if (file == null) {
            return R.failed("文件不存在:" + fileId);
        }
        return R.success("文件查询成功", file);
    }

    @Override
    public R<ThirdFile> saveFileNewVersion(String fileId, MultipartFile file) {
        R<ThirdFile> getLast = getLatestFileByFileId(fileId);
        if (getLast.getResult() == 0) {
            File destFile = new File(getFileSavePath(fileId,getLast.getData().getName(),getLast.getData().getVersion() + 1));
            log.info("文件新版本，保存的目录:{}",destFile.getAbsolutePath());
            try {
                file.transferTo(destFile);
                ThirdFile newFile = ThirdFile.builder()
                        .groupFileId(fileId)
                        .id(fileId + '-' + (getLast.getData().getVersion() + 1))
                        .version(getLast.getData().getVersion() + 1)
                        .createTime(DateUtil.getCurrentSeconds())
                        .updateTime(DateUtil.getCurrentSeconds())
                        .size(destFile.length())
                        .name(getLast.getData().getName()).build();
                int result = fileMapper.insert(newFile);
                if (result > 0) {
                    return R.success("新版本保存成功", newFile);
                }
                return R.failed("新版本保存失败");
            } catch (Exception e) {
                log.error("移动文件发生错误", e);
                return R.failed("保存新版本失败，移动文件发生错误:" + fileId);
            }
        } else {
            log.error("文件不存在");
        }
        return R.failed("文件不存在");
    }

    @Override
    public R<ThirdFile> getFileByVersion(String fileId, Integer version) {
        LambdaQueryWrapper<ThirdFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdFile::getGroupFileId, fileId);
        queryWrapper.eq(ThirdFile::getVersion, version);
        ThirdFile file = fileMapper.selectOne(queryWrapper);
        if (file != null) {
            return R.success("获取文件特定版本成功", file);
        } else {
            return R.failed("文件版本不存在");
        }
    }

    @Override
    public R<List<ThirdFile>> getFileHistory(String fileId) {
        LambdaQueryWrapper<ThirdFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdFile::getGroupFileId, fileId);
        queryWrapper.orderByDesc(ThirdFile::getVersion);
        List<ThirdFile> data = fileMapper.selectList(queryWrapper);
        return R.success("获取成功", data);
    }

    @Override
    public String getFileSavePath(String fileId, String filename, Integer version) {
        if (StringUtils.equals(fileId, WdztAppInfoConfig.templateWordId)
                || StringUtils.equals(fileId, WdztAppInfoConfig.templateExcelId)
                || StringUtils.equals(fileId, WdztAppInfoConfig.templateImgWaterId)
                || StringUtils.equals(fileId, WdztAppInfoConfig.templatePptId)
                || StringUtils.equals(fileId, WdztAppInfoConfig.templatePdfId)
                || StringUtils.equals(fileId, WdztAppInfoConfig.templateZipId)) {
            if (version == 1) {
                return getFileSavePath(fileId);
            }
        }
        String ext = filename.substring(filename.lastIndexOf("."));
        return String.format("%s%s%s", savePath, File.separator, fileId + version + ext);
    }

    @Override
    public String getFileSavePath(String fileId) {
        if (StringUtils.equals(WdztAppInfoConfig.templateExcelId, fileId)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.xlsx";
        }
        if (StringUtils.equals(WdztAppInfoConfig.templateWordId, fileId)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.docx";
        }
        if (StringUtils.equals(WdztAppInfoConfig.templatePdfId, fileId)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.pdf";
        }
        if (StringUtils.equals(WdztAppInfoConfig.templatePptId, fileId)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.pptx";
        }
        if (StringUtils.equals(WdztAppInfoConfig.templateImgWaterId, fileId)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "water.png";
        }
        if (StringUtils.equals(WdztAppInfoConfig.templateZipId, fileId)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.zip";
        }
        return null;
    }

    @Override
    public R<InputStream> getTemplateFile(String fileId) {
        log.info("fileId {} fileSavePath = {}", fileId, getFileSavePath(fileId));
        Resource resource = resourceLoader.getResource(getFileSavePath(fileId));
        try {
            return R.success("读取模版成功", resource.getInputStream());
        } catch (Exception error) {
            log.error("读取模版发生错误", error);
            return R.failed("读取模版发生错误");
        }
    }

    @Override
    public R<Long> getTemplateSize(String fileId) {
        Resource resource = resourceLoader.getResource(getFileSavePath(fileId));
        try {
            return R.success("读取模版成功", resource.contentLength());
        } catch (Exception error) {
            log.error("读取模版发生错误", error);
            return R.failed("读取模版发生错误");
        }
    }

    @Override
    public R<ThirdFile> createTemplateFile(String type) {
        String name;
        String fileId;
        if (StringUtils.equals(type, "xlsx")) {
            fileId = WdztAppInfoConfig.templateExcelId;
            name = "测试文件.xlsx";
        } else if (StringUtils.equals(type, "docx")) {
            fileId = WdztAppInfoConfig.templateWordId;
            name = "测试文件.docx";
        } else if (StringUtils.equals(type, "pptx")) {
            fileId = WdztAppInfoConfig.templatePptId;
            name = "测试文件.pptx";
        } else if (StringUtils.equals(type, "pdf")) {
            fileId = WdztAppInfoConfig.templatePdfId;
            name = "测试文件.pdf";
        } else if (StringUtils.equals(type, "png")) {
            fileId = WdztAppInfoConfig.templateImgWaterId;
            name = "水印文件.png";
        } else if (StringUtils.equals(type, "zip")) {
            fileId = WdztAppInfoConfig.templateZipId;
            name = "压缩文件.zip";
        }else {
            return R.failed("文件类型不支持");
        }
        ThirdFile file = fileMapper.selectById(generateVersionFileId(fileId, 1));
        if (file != null) {
            return R.success("文件存在，使用旧文档", file);
        }
        file = ThirdFile.builder()
                .id(generateVersionFileId(fileId, 1))
                .name(name)
                .version(1)
                .createTime(DateUtil.getCurrentSeconds())
                .updateTime(DateUtil.getCurrentSeconds())
                .size(getTemplateSize(fileId).getData())
                .groupFileId(fileId)
                .build();
        int insertResult = fileMapper.insert(file);
        return insertResult > 0 ? R.success("创建模版文件成功", file) : R.failed("文件模版创建失败");
    }

    @Override
    public R<InputStream> downloadFile(String fileId, Integer version) {
        R<ThirdFile> dbFile = getFileByFileVersionId(generateVersionFileId(fileId, version));
        if (dbFile.getResult() != 0) {
            return R.failed(dbFile.getMessage());
        }
        ThirdFile file = dbFile.getData();
        if (StringUtils.equals(WdztAppInfoConfig.templateWordId,fileId)
                ||StringUtils.equals(WdztAppInfoConfig.templateExcelId,fileId)
                ||StringUtils.equals(WdztAppInfoConfig.templatePptId,fileId)
                ||StringUtils.equals(WdztAppInfoConfig.templatePdfId,fileId)
                ||StringUtils.equals(WdztAppInfoConfig.templateImgWaterId,fileId)
                ||StringUtils.equals(WdztAppInfoConfig.templateZipId,fileId)){
            if (version == 1) {
                return getTemplateFile(fileId);
            }
        }

        File fileVersion = new File(getFileSavePath(fileId, file.getName(), file.getVersion()));
        log.info("要下载的文件地址为：{}",fileVersion.getAbsolutePath());
        if (fileVersion.exists()) {
            try {
                return R.success("获取文件成功", Files.newInputStream(fileVersion.toPath()));
            } catch (Exception e) {
                return R.failed(e.getMessage());
            }
        }
        return R.failed("文件不存在");
    }

    @Override
    public String getDownloadUrl(String fileId, Integer version) {
        return String.format("%s%s?file_id=%s&version=%s", downloadUrl, "/download/file", fileId, version);
    }

    @Override
    public String generateVersionFileId(String fileId, Integer version) {
        return String.format("%s-%s", fileId, version);
    }

    @Override
    public R<String> getFileType(String filename) {
        String type = WPS4Util.getFileType(filename);
        return type != null ? R.success("获取成功", type) : R.failed("文件不支持");
    }

    @Override
    public void resetFile() {
        fileMapper.delete(null);
    }
}
